﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting;
using System.IO;
using IronPython.Hosting;
using System.Reflection;
using Microsoft.SharePoint;
using System.Web.UI;

namespace IronSharePoint
{
    public class IronScriptEngine
    {
        public IIronScriptResolver ScriptResolver { get; set; }

        public Microsoft.Scripting.Hosting.ScriptEngine BaseEngine { get; set; }
        public ScriptScope Scope { get; set; }
        public ScriptSource Source { get; set; }
        public ObjectOperations Operations { get; set; }

        private bool _isInitilized = false;
        public bool IsInitialized
        {
            get { return _isInitilized; }
        }

        public IronScriptEngine()
        {
            this.ScriptResolver = new IronScriptResolver();
        }

        public IronScriptEngine(IIronScriptResolver resolver)
        {
            this.ScriptResolver = resolver;
        }

        public void CompileScript(string script, IronScriptingLanguage language, params Assembly[] assemblies)
        {
            BaseEngine = GetEngine(language);
            BaseEngine.Runtime.LoadAssembly(Assembly.GetExecutingAssembly());
            BaseEngine.Runtime.LoadAssembly(typeof(String).Assembly);
            BaseEngine.Runtime.LoadAssembly(typeof(SPSite).Assembly);

            foreach (Assembly assemblie in assemblies)
            {
                BaseEngine.Runtime.LoadAssembly(assemblie);
            }

            ICollection<string> searchPaths = BaseEngine.GetSearchPaths();
                       
            ScriptResolver.SearchPaths.AddRange(searchPaths);
            BaseEngine.SetSearchPaths(ScriptResolver.SearchPaths);

            Scope = BaseEngine.CreateScope();

            if (String.IsNullOrEmpty(ScriptResolver.ScriptPath) || ScriptResolver.ScriptPath.StartsWith("http://"))
            {
                string tmpPath = Path.GetTempFileName() + ".py";
                File.WriteAllText(tmpPath, script);
                Source = BaseEngine.CreateScriptSourceFromFile(tmpPath);
            }
            else
            {
                Source = BaseEngine.CreateScriptSourceFromFile(ScriptResolver.ScriptPath);
            }
            //Source = BaseEngine.CreateScriptSourceFromString(script, SourceCodeKind.Statements);

            CompiledCode code = Source.Compile();

            code.Execute(Scope);

            Operations = BaseEngine.CreateOperations();

            _isInitilized = true;
        }

        public void CompileScriptFrom(string scriptPath, params Assembly[] assemblies)
        {
            string script = ScriptResolver.GetScript(scriptPath);

            string extension = Path.GetExtension(ScriptResolver.ScriptPath);
            IronScriptingLanguage language = IronScriptingLanguage.Unknown;

            switch (extension)
            {
                case ".py": language = IronScriptingLanguage.IronPython; break;
                default:
                    break;
            }

            CompileScript(script, language, assemblies);

        }


        protected virtual Microsoft.Scripting.Hosting.ScriptEngine GetEngine(IronScriptingLanguage language)
        {
            Microsoft.Scripting.Hosting.ScriptEngine engine = null;

            IDictionary<string, object> options = new Dictionary<string, object>();

            options["PrivateBinding"]=true;
            options["Debug"]=true;
            //options["FullFrames"]=true; 


            switch (language)
            {
                case IronScriptingLanguage.IronPython: engine = Python.CreateEngine(options); break;
                default:
                    break;
            }

            return engine;
        }




    }
}
